package com.example.myapplication;

import android.graphics.Color;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.bumptech.glide.Glide;
import com.example.myapplication.R;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MusicFragment extends Fragment implements MusicAdapter.OnItemClickListener {

    private static final String TAG = "MusicFragment";

    private EditText searchEditText;
    private Button searchButton;
    private RecyclerView musicRecyclerView;
    private TextView currentSongTextView;
    private Button playPauseButton;
    private ImageView albumArtImageView;
    private RecyclerView lyricsRecyclerView;
    private SeekBar seekBarProgress;
    private TextView currentTimeTextView;
    private TextView totalTimeTextView;
    private LinearLayout mediaInfoLayout;

    private MusicAdapter musicAdapter;
    private LyricAdapter lyricAdapter;
    private List<Song> songList;
    private MediaPlayer mediaPlayer;
    private Song currentPlayingSong;

    private Handler handler = new Handler();
    private Runnable updateProgressAction;

    private List<LyricLine> parsedLyrics;

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        View root = inflater.inflate(R.layout.fragment_music, container, false);

        searchEditText = root.findViewById(R.id.edit_text_search);
        searchButton = root.findViewById(R.id.button_search);
        musicRecyclerView = root.findViewById(R.id.recycler_view_music);
        currentSongTextView = root.findViewById(R.id.text_view_current_song);
        playPauseButton = root.findViewById(R.id.button_play_pause);
        albumArtImageView = root.findViewById(R.id.image_view_album_art);
        lyricsRecyclerView = root.findViewById(R.id.recycler_view_lyrics);
        seekBarProgress = root.findViewById(R.id.seek_bar_progress);
        currentTimeTextView = root.findViewById(R.id.text_view_current_time);
        totalTimeTextView = root.findViewById(R.id.text_view_total_time);
        mediaInfoLayout = root.findViewById(R.id.media_info_layout);

        songList = new ArrayList<>();
        musicAdapter = new MusicAdapter(songList);
        musicRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
        musicRecyclerView.setAdapter(musicAdapter);
        musicAdapter.setOnItemClickListener(this);

        parsedLyrics = new ArrayList<>();
        lyricAdapter = new LyricAdapter(parsedLyrics);
        lyricsRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
        lyricsRecyclerView.setAdapter(lyricAdapter);

        mediaPlayer = new MediaPlayer();
        mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);

        searchButton.setOnClickListener(v -> {
            String query = searchEditText.getText().toString();
            if (!query.isEmpty()) {
                mediaInfoLayout.setVisibility(View.GONE);
                musicRecyclerView.setVisibility(View.VISIBLE);
                new FetchMusicListTask().execute(query);
            } else {
                Toast.makeText(getContext(), "请输入搜索内容", Toast.LENGTH_SHORT).show();
            }
        });

        playPauseButton.setOnClickListener(v -> {
            if (mediaPlayer != null) {
                if (mediaPlayer.isPlaying()) {
                    mediaPlayer.pause();
                    playPauseButton.setText("播放");
                    handler.removeCallbacks(updateProgressAction);
                } else {
                    mediaPlayer.start();
                    playPauseButton.setText("暂停");
                    handler.post(updateProgressAction);
                }
            }
        });

        seekBarProgress.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                if (fromUser && mediaPlayer != null) {
                    mediaPlayer.seekTo(progress);
                    currentTimeTextView.setText(formatTime(progress));
                    updateLyrics(progress);
                }
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                if (mediaPlayer != null) {
                    handler.removeCallbacks(updateProgressAction);
                }
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                if (mediaPlayer != null) {
                    handler.post(updateProgressAction);
                }
            }
        });

        updateProgressAction = new Runnable() {
            @Override
            public void run() {
                if (mediaPlayer != null && mediaPlayer.isPlaying()) {
                    int currentPosition = mediaPlayer.getCurrentPosition();
                    seekBarProgress.setProgress(currentPosition);
                    currentTimeTextView.setText(formatTime(currentPosition));
                    updateLyrics(currentPosition);
                }
                handler.postDelayed(this, 1000);
            }
        };

        return root;
    }

    @Override
    public void onItemClick(Song song) {
        currentPlayingSong = song;
        new FetchMusicUrlTask().execute(song);
        mediaInfoLayout.setVisibility(View.VISIBLE);
        musicRecyclerView.setVisibility(View.GONE);
    }

    private void playSong(Song songWithDetails) {
        if (mediaPlayer != null) {
            mediaPlayer.stop();
            mediaPlayer.reset();
        }

        try {
            mediaPlayer.setDataSource(songWithDetails.getMusicUrl());
            mediaPlayer.prepareAsync();
            mediaPlayer.setOnPreparedListener(mp -> {
                mp.start();
                currentSongTextView.setText("当前播放: " + songWithDetails.getName() + " - " + songWithDetails.getArtist());
                playPauseButton.setText("暂停");
                seekBarProgress.setMax(mp.getDuration());
                totalTimeTextView.setText(formatTime(mp.getDuration()));
                handler.post(updateProgressAction);

                if (getContext() != null && songWithDetails.getPicUrl() != null && !songWithDetails.getPicUrl().isEmpty()) {
                    Glide.with(this).load(songWithDetails.getPicUrl()).into(albumArtImageView);
                } else {
                    albumArtImageView.setImageResource(android.R.drawable.ic_menu_gallery);
                }

                if (songWithDetails.getLrc() != null && !songWithDetails.getLrc().isEmpty()) {
                    parsedLyrics = parseLrc(songWithDetails.getLrc());
                    lyricAdapter.setLyrics(parsedLyrics);
                    updateLyrics(0);
                } else {
                    lyricAdapter.setLyrics(new ArrayList<>());
                    lyricsRecyclerView.scrollToPosition(0);
                }
            });
            mediaPlayer.setOnCompletionListener(mp -> {
                playPauseButton.setText("播放");
                currentSongTextView.setText("当前播放: 无");
                currentPlayingSong = null;
                seekBarProgress.setProgress(0);
                currentTimeTextView.setText("00:00");
                handler.removeCallbacks(updateProgressAction);
                albumArtImageView.setImageResource(android.R.drawable.ic_menu_gallery);
                lyricAdapter.setLyrics(new ArrayList<>());
                lyricsRecyclerView.scrollToPosition(0);
            });
            mediaPlayer.setOnErrorListener((mp, what, extra) -> {
                Toast.makeText(getContext(), "播放错误", Toast.LENGTH_SHORT).show();
                Log.e(TAG, "MediaPlayer Error: what=" + what + ", extra=" + extra);
                playPauseButton.setText("播放");
                currentSongTextView.setText("当前播放: 无");
                currentPlayingSong = null;
                seekBarProgress.setProgress(0);
                currentTimeTextView.setText("00:00");
                handler.removeCallbacks(updateProgressAction);
                albumArtImageView.setImageResource(android.R.drawable.ic_menu_gallery);
                lyricAdapter.setLyrics(new ArrayList<>());
                lyricsRecyclerView.scrollToPosition(0);
                return true;
            });
        } catch (IOException e) {
            Log.e(TAG, "Error setting data source: " + e.getMessage(), e);
            Toast.makeText(getContext(), "无法播放歌曲: " + e.getMessage(), Toast.LENGTH_SHORT).show();
            playPauseButton.setText("播放");
            currentSongTextView.setText("当前播放: 无");
            currentPlayingSong = null;
            seekBarProgress.setProgress(0);
            currentTimeTextView.setText("00:00");
            handler.removeCallbacks(updateProgressAction);
            albumArtImageView.setImageResource(android.R.drawable.ic_menu_gallery);
            lyricAdapter.setLyrics(new ArrayList<>());
            lyricsRecyclerView.scrollToPosition(0);
        }
    }

    private String formatTime(int milliseconds) {
        SimpleDateFormat sdf = new SimpleDateFormat("mm:ss", Locale.getDefault());
        return sdf.format(new java.util.Date(milliseconds));
    }

    private void updateLyrics(int currentPosition) {
        if (parsedLyrics != null && !parsedLyrics.isEmpty()) {
            int currentLyricIndex = -1;
            for (int i = parsedLyrics.size() - 1; i >= 0; i--) {
                LyricLine line = parsedLyrics.get(i);
                if (currentPosition >= line.timestamp) {
                    currentLyricIndex = i;
                    break;
                }
            }
            if (currentLyricIndex != -1) {
                lyricAdapter.highlightLyric(currentLyricIndex);
                LinearLayoutManager layoutManager = (LinearLayoutManager) lyricsRecyclerView.getLayoutManager();
                if (layoutManager != null) {
                    // Calculate the position to scroll to center the current lyric
                    View view = layoutManager.findViewByPosition(currentLyricIndex);
                    if (view != null) {
                        int centerY = lyricsRecyclerView.getHeight() / 2;
                        int viewCenterY = view.getTop() + view.getHeight() / 2;
                        int scrollDelta = viewCenterY - centerY;
                        lyricsRecyclerView.smoothScrollBy(0, scrollDelta);
                    }
                }
            } else {
                lyricAdapter.highlightLyric(-1); // No lyric to highlight
            }
        }
    }

    public static class LyricLine {
        long timestamp;
        String lyric;

        public LyricLine(long timestamp, String lyric) {
            this.timestamp = timestamp;
            this.lyric = lyric;
        }
    }

    private List<LyricLine> parseLrc(String lrcContent) {
        List<LyricLine> lines = new ArrayList<>();
        Pattern pattern = Pattern.compile("\\Q[\\E(\\d{2}):(\\d{2})\\Q.\\E(\\d{2,3})\\Q]\\E(.*)");
        String[] lrcLines = lrcContent.split("\n");

        for (String line : lrcLines) {
            Matcher matcher = pattern.matcher(line);
            while (matcher.find()) {
                long minutes = Long.parseLong(matcher.group(1));
                long seconds = Long.parseLong(matcher.group(2));
                long millis = Long.parseLong(matcher.group(3));
                if (matcher.group(3).length() == 2) {
                    millis *= 10;
                }
                long timestamp = minutes * 60 * 1000 + seconds * 1000 + millis;
                String lyric = matcher.group(4).trim();
                lines.add(new LyricLine(timestamp, lyric));
            }
        }

        Collections.sort(lines, Comparator.comparingLong(line -> line.timestamp));
        return lines;
    }

    private class FetchMusicListTask extends AsyncTask<String, Void, List<Song>> {

        @Override
        protected List<Song> doInBackground(String... params) {
            String query = params[0];
            String encodedQuery = null;
            try {
                encodedQuery = URLEncoder.encode(query, "UTF-8");
            } catch (IOException e) {
                Log.e(TAG, "Error encoding query: " + e.getMessage(), e);
                return null;
            }
            String urlString = "https://api.jkyai.top/API/hqyyid.php?name=" + encodedQuery + "&type=wy&page=1&limit=20";
            Log.d(TAG, "Searching for: " + query + ", URL: " + urlString);
            HttpURLConnection urlConnection = null;
            BufferedReader reader = null;
            List<Song> results = new ArrayList<>();

            try {
                URL url = new URL(urlString);
                urlConnection = (HttpURLConnection) url.openConnection();
                urlConnection.setRequestMethod("GET");
                urlConnection.connect();

                int responseCode = urlConnection.getResponseCode();
                Log.d(TAG, "HTTP Response Code: " + responseCode);

                if (responseCode == HttpURLConnection.HTTP_OK) {
                    InputStreamReader inputStream = new InputStreamReader(urlConnection.getInputStream());
                    reader = new BufferedReader(inputStream);
                    StringBuilder buffer = new StringBuilder();
                    String line;
                    while ((line = reader.readLine()) != null) {
                        buffer.append(line);
                    }

                    String jsonResponse = buffer.toString();
                    Log.d(TAG, "API Response: " + jsonResponse);

                    JSONObject jsonObject = new JSONObject(jsonResponse);
                    Log.d(TAG, "Parsed JSONObject: " + jsonObject.toString());

                    JSONArray dataArray = jsonObject.optJSONArray("data");
                    Log.d(TAG, "Data Array is null: " + (dataArray == null));
                    if (dataArray != null) {
                        Log.d(TAG, "Data Array length: " + dataArray.length());
                        for (int i = 0; i < dataArray.length(); i++) {
                            JSONObject songJson = dataArray.getJSONObject(i);
                            Log.d(TAG, "Processing song JSON: " + songJson.toString());
                            String name = songJson.optString("name");
                            String artist = songJson.optString("artist");
                            String songId = songJson.optString("id");
                            if (!name.isEmpty() && !songId.isEmpty()) {
                                results.add(new Song(name, artist, songId));
                            } else {
                                Log.w(TAG, "Skipping song due to empty name or songId: " + songJson.toString());
                            }
                        }
                    } else {
                        Log.e(TAG, "Data array is null in JSON response.");
                    }
                } else {
                    Log.e(TAG, "HTTP Error: " + responseCode + " - " + urlConnection.getResponseMessage());
                }
            } catch (IOException e) {
                Log.e(TAG, "Network Error: " + e.getMessage(), e);
            } catch (JSONException e) {
                Log.e(TAG, "JSON Parsing Error: " + e.getMessage(), e);
            } finally {
                if (urlConnection != null) {
                    urlConnection.disconnect();
                }
                if (reader != null) {
                    try {
                        reader.close();
                    } catch (IOException e) {
                        Log.e(TAG, "Error closing reader: " + e.getMessage(), e);
                    }
                }
            }
            return results;
        }

        @Override
        protected void onPostExecute(List<Song> songs) {
            super.onPostExecute(songs);
            if (songs != null && !songs.isEmpty()) {
                Log.d(TAG, "Found " + songs.size() + " songs.");
                musicAdapter.updateSongList(songs);
            } else {
                Toast.makeText(getContext(), "未找到音乐", Toast.LENGTH_SHORT).show();
                musicAdapter.updateSongList(new ArrayList<>());
                Log.d(TAG, "No songs found.");
            }
        }
    }

    private class FetchMusicUrlTask extends AsyncTask<Song, Void, Song> {

        @Override
        protected Song doInBackground(Song... songs) {
            Song song = songs[0];
            String songId = song.getSongId();
            String urlString = "https://api.jkyai.top/API/yyjhss.php?id=" + songId + "&type=wy";
            Log.d(TAG, "Fetching music URL for songId: " + songId + ", URL: " + urlString);
            HttpURLConnection urlConnection = null;
            BufferedReader reader = null;

            try {
                URL url = new URL(urlString);
                urlConnection = (HttpURLConnection) url.openConnection();
                urlConnection.setRequestMethod("GET");
                urlConnection.connect();

                int responseCode = urlConnection.getResponseCode();
                Log.d(TAG, "HTTP Response Code (URL Fetch): " + responseCode);

                if (responseCode == HttpURLConnection.HTTP_OK) {
                    InputStreamReader inputStream = new InputStreamReader(urlConnection.getInputStream());
                    reader = new BufferedReader(inputStream);
                    StringBuilder buffer = new StringBuilder();
                    String line;
                    while ((line = reader.readLine()) != null) {
                        buffer.append(line);
                    }

                    String jsonResponse = buffer.toString();
                    Log.d(TAG, "Music URL API Response: " + jsonResponse);

                    JSONObject jsonObject = new JSONObject(jsonResponse);
                    JSONObject dataObject = jsonObject.optJSONObject("data");
                    if (dataObject != null) {
                        song.setMusicUrl(dataObject.optString("url"));
                        song.setPicUrl(dataObject.optString("pic"));
                        song.setLrc(dataObject.optString("lrc"));
                    }

                } else {
                    Log.e(TAG, "HTTP Error (URL Fetch): " + responseCode + " - " + urlConnection.getResponseMessage());
                }
            } catch (IOException e) {
                Log.e(TAG, "Network Error (URL Fetch): " + e.getMessage(), e);
            } catch (JSONException e) {
                Log.e(TAG, "JSON Parsing Error (URL Fetch): " + e.getMessage(), e);
            } finally {
                if (urlConnection != null) {
                    urlConnection.disconnect();
                }
                if (reader != null) {
                    try {
                        reader.close();
                    } catch (IOException e) {
                        Log.e(TAG, "Error closing reader (URL Fetch): " + e.getMessage(), e);
                    }
                }
            }
            return song;
        }

        @Override
        protected void onPostExecute(Song updatedSong) {
            super.onPostExecute(updatedSong);
            if (updatedSong != null && updatedSong.getMusicUrl() != null && !updatedSong.getMusicUrl().isEmpty()) {
                Log.d(TAG, "Music URL found: " + updatedSong.getMusicUrl());
                playSong(updatedSong);
            } else {
                Toast.makeText(getContext(), "无法获取歌曲播放链接", Toast.LENGTH_SHORT).show();
                Log.d(TAG, "No music URL found for songId: " + (updatedSong != null ? updatedSong.getSongId() : "N/A"));
            }
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mediaPlayer != null) {
            mediaPlayer.release();
            mediaPlayer = null;
        }
        handler.removeCallbacks(updateProgressAction);
    }
}